package xcmg.device.service.prepPay;

import com.github.pagehelper.PageInfo;
import yb.ecp.fast.infra.util.PageHelperPlus;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import xcmg.device.dao.entity.company.CompanyDealerDO;
import xcmg.device.dao.entity.prepPay.PrepPayDO;
import xcmg.device.dao.mapper.CompanyDealerMapper;
import xcmg.device.dao.mapper.account.ArapMapper;
import xcmg.device.dao.mapper.prepPay.PrepPayDOMapper;
import xcmg.device.infra.ErrorCode;
import xcmg.device.infra.ExportUtil;
import xcmg.device.infra.enums.PrepPayBillTypeEnum;
import xcmg.device.infra.enums.WhetherTypeEnum;
import xcmg.device.service.account.ArapService;
import xcmg.device.service.vo.FunctionResult;
import xcmg.device.service.vo.prepPay.PrepPayAddVO;
import xcmg.device.service.vo.prepPay.PrepPayDiscardVO;
import xcmg.device.service.vo.prepPay.PrepPayQueryVO;
import xcmg.device.service.vo.prepPay.PrepPayShowVO;
import yb.ecp.fast.feign.FastGenClient;
import yb.ecp.fast.infra.infra.PageCommonVO;
import yb.ecp.fast.infra.infra.SearchCommonVO;
import yb.ecp.fast.infra.infra.log.LogHelper;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author: xiali@bkrwin.com
 * @description: 预付款功能Service
 * @date： 2019/6/6 9:30
 **/

@Service
public class PrepPayService {
    @Autowired
    PrepPayDOMapper prepPayDOMapper;
    @Autowired
    FastGenClient fastGenClient;
    @Autowired
    ArapService arapService;
    @Autowired
    CompanyDealerMapper companyDealerMapper;
    @Autowired
    ArapMapper arapMapper;
    @Autowired
    private HttpServletResponse response;
    private static final SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    /**
     * 新增结算卡记录
     *
     * @param
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ErrorCode add(PrepPayAddVO prepPayAddVO,String userId,String orgId)throws Exception{
        PrepPayDO prepPayDO = new PrepPayDO();
        BeanUtils.copyProperties(prepPayAddVO, prepPayDO);
        prepPayDO.setId(fastGenClient.textGuid().getValue());
        prepPayDO.setCreateId(userId);
        CompanyDealerDO companyDealerDO = companyDealerMapper.item(Long.valueOf(prepPayAddVO.getCustomerId()));
        if(companyDealerDO == null){
            LogHelper.error("客户信息不存在", ErrorCode.Failure.getCode());
            throw new Exception("客户信息不存在");
        }
        prepPayDO.setCustomerName(companyDealerDO.getCompanyName());
        prepPayDO.setOrgId(orgId);
        prepPayDO.setDiscardFlag(0);
        prepPayDO.setCreateDate(new Date());
        Boolean success = prepPayDOMapper.insert(prepPayDO)>0;
        if(!success){
            LogHelper.error("新增结算卡记录失败", ErrorCode.Failure.getCode());
            throw new Exception("操作失败");
        }
        FunctionResult result = arapService.addOrUpdateArapDO(prepPayDO,orgId);
        if(result.getCode() != ErrorCode.Success){
            throw new Exception("操作失败");
        }
        prepPayDO.setTotalAmount((BigDecimal)result.getValue());
        success = prepPayDOMapper.updateByPrimaryKeySelective(prepPayDO)>0;
        if(!success){
            LogHelper.error("更新结算卡记录失败", ErrorCode.Failure.getCode());
            throw new Exception("操作失败");
        }
        return ErrorCode.Success;
    }




    /**
    * 查询结算卡记录
    * 1."结算卡"页面查询接口
    * @param condition 前端传参包含 customerId： 商户ID，选填,
    *                              startDate：起始时间，选填,
    *                              endDate：截止时间，选填,
    *                              queryPageFlag：是否为查询页面，默认true，必填
    *                              orgId在Controller层获取。
    * @return billType为0的商户结算卡记录List-带分页
    *
    * 2.同时兼容"应收"菜单-预收款金额-点击链接
    * @param  condition 前端传参：customerId 商户ID，必填;
    *                            queryPageFlag： 是否为查询页面，默认false，必填;
    *                            orgId在Controller层获取。
    * @return 选中商户的结算卡记录List-带分页
    */

    public PageCommonVO list(SearchCommonVO<PrepPayQueryVO> condition){
        if (condition.getFilters().getQueryPageFlag()) {
            PageCommonVO<PrepPayShowVO> pageCommonVO = new PageCommonVO();
            condition.getFilters().setBillType(0);

            PageHelperPlus.orderBy("create_date desc");
            PageHelperPlus.startPage(condition.getPageNum(), condition.getPageSize());
            List<PrepPayDO> doList = prepPayDOMapper.getListByQueryVO(condition.getFilters());
            List<PrepPayShowVO> voList = new ArrayList<>();
            for (PrepPayDO entity : doList) {
                PrepPayShowVO model = new PrepPayShowVO();
                BeanUtils.copyProperties(entity, model);
                voList.add(model);
            }
            pageCommonVO.setPageInfo(new PageInfo(doList));
            pageCommonVO.setPageInfoList(voList);
            return pageCommonVO;
        }else {
            PageCommonVO<PrepPayShowVO> pageCommonVO = new PageCommonVO();
            CompanyDealerDO companyDealerDO = companyDealerMapper.itemByOrgId(condition.getFilters().getOrgId(),
                    condition.getFilters().getCustomerId());
            if (companyDealerDO == null) {
                return pageCommonVO;
            }
            condition.getFilters().setCustomerId(String.valueOf(companyDealerDO.getId()));

            PageHelperPlus.orderBy("create_date desc");
            PageHelperPlus.startPage(condition.getPageNum(), condition.getPageSize());
            List<PrepPayDO> doList = prepPayDOMapper.getListByQueryVO(condition.getFilters());
            List<PrepPayShowVO> voList = new ArrayList<>();
            for (PrepPayDO entity : doList) {
                PrepPayShowVO model = new PrepPayShowVO();
                BeanUtils.copyProperties(entity, model);
                BigDecimal totalAmount = model.getTotalAmount() == null ? BigDecimal.ZERO : model.getTotalAmount();
                BigDecimal transactionAmount = model.getTransactionAmount() == null ? BigDecimal.ZERO : model.getTransactionAmount();
                model.setOriginalAmount(totalAmount.subtract(transactionAmount));
                voList.add(model);
            }
            pageCommonVO.setPageInfo(new PageInfo(doList));
            pageCommonVO.setPageInfoList(voList);
            return pageCommonVO;
        }
    }


    /**
     * 作废结算卡记录
     *
     * @param
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ErrorCode discard(PrepPayDiscardVO prepPayDiscardVO , String userId,String orgId)throws Exception{
        PrepPayDO prepPayDO = prepPayDOMapper.selectByPrimaryKey(prepPayDiscardVO.getId());
        if (prepPayDO == null||prepPayDO.getTransactionAmount()==null){
            return ErrorCode.Failure;
        }
        BigDecimal transactionAmount = prepPayDO.getTransactionAmount();
        prepPayDO.setTransactionAmount(transactionAmount.negate());
        FunctionResult result = arapService.addOrUpdateArapDO(prepPayDO,orgId);
        if(result.getCode() != ErrorCode.Success){
            LogHelper.error("更新预付款金额失败", ErrorCode.Failure.getCode());
            return result.getCode();
        }
        prepPayDO.setTransactionAmount(transactionAmount);
        prepPayDO.setDiscardFlag(1);
        prepPayDO.setDiscardDate(new Date());
        prepPayDO.setDiscardPersonId(userId);
        prepPayDO.setDiscardRemark(prepPayDiscardVO.getDiscardRemark());
        Boolean success = prepPayDOMapper.updateByPrimaryKey(prepPayDO)>0;
        if(!success){
            LogHelper.error("作废结算卡记录失败", ErrorCode.Failure.getCode());
            throw new Exception("操作失败");
        }
        return ErrorCode.Success;
    }


    /**
     * 勾选数据进行导出
     *
     * @param
     * @return
     */
    public void export(List<String> ids)throws Exception{
        PageHelperPlus.orderBy("create_date desc");
        invokeExport(prepPayDOMapper.findByIds(ids));
    }
    /**
     * 导出当前页面展示数据
     *
     * @param
     * @return
     */
    public void exportAll(PrepPayQueryVO condition)throws Exception{
        condition.setBillType(0);
        Integer count = prepPayDOMapper.listCount(condition);
        List<PrepPayDO> dataList = new ArrayList<>();
        int times = count/500+1;
        for(int i=0; i<times; i++){
            PageHelperPlus.startPage(i + 1, 500, "create_date desc");
            dataList.addAll(prepPayDOMapper.getListByQueryVO(condition));
        }
        invokeExport(dataList);
    }

    private void invokeExport(List<PrepPayDO> doList)throws Exception{
        String title = "结算卡数据导出";
        String[] rowsName = new String[]{"序号", "客户名称", "单据类型", "交易金额", "总金额", "创建时间", "是否红冲", "红冲时间", "充值备注","红冲备注"};
        List<Object[]>  dataList = new ArrayList<Object[]>();
        Object[] objs;
        for (int i = 0; i < doList.size(); i++) {
            PrepPayDO exportDO = doList.get(i);
            objs = new Object[rowsName.length];
            objs[0] = i+1;
            objs[1] = exportDO.getCustomerName();
            objs[2] = exportDO.getBillType()==0? PrepPayBillTypeEnum.RECHARGE.getStatusName():"";
            objs[3] = exportDO.getTransactionAmount();
            objs[4] = exportDO.getTotalAmount();
            objs[5] = format.format(exportDO.getCreateDate());
            objs[6] = exportDO.getDiscardFlag()==0 ? WhetherTypeEnum.NoFlag.getDesc():WhetherTypeEnum.YesFlag.getDesc();
            if(exportDO.getDiscardFlag() == 0 ){
                objs[7] = "";
            }else {
                objs[7] = format.format(exportDO.getDiscardDate());
            }
            objs[8] = exportDO.getRemark();
            objs[9] = exportDO.getDiscardRemark();
            dataList.add(objs);
        }
        ExportUtil exportUtil = new ExportUtil(title, rowsName, dataList);
        exportUtil.export(response);
    }

    /**
     * 审核
     *
     * @param id
     * @param pass true通过，false 返回
     * @return
     */
    public ErrorCode audit(String id, boolean pass) {
        PrepPayDO prepPayDO = prepPayDOMapper.selectByPrimaryKey(id);
        if (null == prepPayDO) {
            return ErrorCode.AbnormalDetailArgumentError;
        }
        if (pass) {
            prepPayDO.setAuditStatus(1);
        } else {
            prepPayDO.setAuditStatus(0);
        }
        prepPayDOMapper.updateByPrimaryKeySelective(prepPayDO);
        return ErrorCode.Success;
    }

    /**
     * 详情
     * @param id
     * @return
     */
    public PrepPayShowVO item(String id) {
        PrepPayShowVO result = new PrepPayShowVO();
        PrepPayDO checkDO = prepPayDOMapper.selectByPrimaryKey(id);
        if (checkDO == null) {
            return result;
        }
        BeanUtils.copyProperties(checkDO, result);
        CompanyDealerDO companyDealerDO = companyDealerMapper.item(Long.valueOf(checkDO.getCustomerId()));
        if (null == companyDealerDO) {
            return result;
        }
        result.setDealerCode(companyDealerDO.getDealerCode());
        return result;
    }
}
